<?php

namespace app\controller\admin;

use app\common\service\face\FaceDevice;
use app\common\service\redis\PoolRedis;
use app\model\AdminStaff;
use app\model\AdminStaffIcCard;
use app\model\AdminStudentDormitory;
use app\util\ExcelHandle;
use app\util\ReturnCode;
use think\facade\Log;
use think\facade\Queue;
use think\facade\Request;
use think\facade\Validate;
use think\Response;

// ic卡（一对多），仅职工，学生的ic卡只能有一张
class IcCard extends Base
{
    // 搜索可添加ic卡的用户
    public function userSearch(): Response {
        $school_id = Request::get('school_id/d');
        $keywords = $this->request->get('name', '');

        $obj = AdminStaff::alias('s')
            ->join(['admin_staff_ic_card' => 'c'], 's.id=c.staff_id')
            ->where('c.is_delete', 0)->where('s.is_delete', 0);

        $card_obj = AdminStaffIcCard::where('is_delete', 0)
            ->whereNotNull('ic_card')
            ->where('ic_card', '<>', '');
        if ($school_id > 0) {
            $obj->where('c.school_id', $school_id);
            $card_obj->where('school_id', $school_id);
        }
        $card_staff = $card_obj->group('staff_id')->column('staff_id');
        $obj->where('c.staff_id','not in', $card_staff);

        if ($keywords) {
            $obj->where('s.name', 'like', "%{$keywords}%");
        }

        $list = $obj->group('s.id')->field('s.id,s.name,s.school_id,s.phone,s.type,s.status')
            ->with('school')
            ->append(['status_text','type_text'])
            ->order('s.create_time', 'DESC')
            ->limit(20)->select()->toArray();
        return $this->buildSuccess([
            'list'  => $list
        ]);
    }

    public function add(): Response {
        $school_id = Request::post('school_id/d');
        $staff_id = Request::post('staff_id/d');
        $card = Request::post('card/s', '', 'strip_tags');
        $check_dor_stu_arr = Request::post('check_dor_stu_arr/a');
        $phone = Request::post('phone/s');
        $validate = Validate::rule([
            'school_id|学校'=>'require',
            'staff_id|学生'=>'require',
            'phone|手机号,' => 'require|mobile',
            'card|卡号' => 'require',
        ]);
        if (!$validate->check(input('post.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $where = [
            'staff_id' => $staff_id,
            'school_id' => $school_id,
            'is_delete' => 0
        ];
        $model = (new AdminStaffIcCard())->where($where)->select();
        if (!$model) {
            return $this->buildFailed(ReturnCode::ADD_FAILED, '未授权宿舍');
        }
        $staff = AdminStaff::find($staff_id);
        $staff->phone = $phone;
        $staff->smart_card = $card;
        if ($staff->type == AdminStaff::STUDENT) {
            $staff->smart_card = $card;
        } else {
            $where['student_dormitory_id'] = $check_dor_stu_arr;
        }
        AdminStaffIcCard::update(['ic_card' => $card], $where);

        if ($staff->save()) {
            $redis = PoolRedis::instance();
            $redis->hSetNx("smartCards", $card, $staff->id);
            FaceDevice::editPerson($staff->id);// 更新人脸设备信息
            return $this->buildSuccess();
        }

        return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
    }

    public function edit(): Response
    {
        $staff_id = Request::post('staff_id/d');
        $card_id = Request::post('id/d', 0);
        $card = Request::post('card/s', '', 'strip_tags');
        $validate = Validate::rule([
            'staff_id|学生'=>'require',
            'card|卡号' => 'require',
        ]);
        if (!$validate->check(input('post.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $staff = AdminStaff::where([
            'id' => $staff_id,
            'is_delete' => 0
        ])->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND);
        }

        $redis = PoolRedis::instance();
        // 修改卡号后重置激活时间
//        if ($staff->type > 0) { // 职工单个ic卡编辑
//            $staff_card = AdminStaffIcCard::find($card_id);
//            $old_card = $staff_card->ic_card;
//            $staff_card->ic_card = $card;
//            if ($old_card && $old_card != $card) {
//                $staff_card->activate_time  = 0;
//
//                // 针对可普锁删除IC卡是根据卡号设计，编辑IC卡后需将旧IC卡删除
//                $distributionKey = AdminStudentDormitory::NO_KEY.$staff->school_id.':'.$staff_card->student_dormitory_id;
//                $redis->hSet($distributionKey.':del_card', $old_card, $staff_id);
//                $redis->expire($distributionKey, 60*60*24*7); // 7*24小时
//            }
//            $staff_card->save();
//        } else { // 学生编辑IC卡，同步修改

        $update['ic_card'] = $card;
        $old_card = $staff->smart_card;
        if ($old_card && $old_card != $card) {
            $update['activate_time'] = 0;

            // 针对可普锁删除IC卡是根据卡号设计，编辑IC卡后需将旧IC卡删除
            $where = [
                'staff_id' => $staff_id,
                'school_id' => $staff->school_id,
                'is_delete' => 0
            ];
            $staffIcCardArr = (new AdminStaffIcCard())->where($where)->select();
            foreach ($staffIcCardArr as $staff_card) {
                $distributionKey = AdminStudentDormitory::NO_KEY.$staff->school_id.':'.$staff_card->student_dormitory_id;
                $redis->hSet($distributionKey.':del_card', $old_card, $staff_id);
                $redis->expire($distributionKey, 60*60*24*7); // 7*24小时
            }
        }
        $staff->smart_card = $card;
        AdminStaffIcCard::update($update, [
            'staff_id' => $staff_id,
            'school_id' => $staff->school_id,
            'is_delete' => 0
        ]);
//        }

        if (AdminStaff::update(['smart_card' => $card, 'id' => $staff->id])) {
            $redis = PoolRedis::instance();
            if ($old_card && $old_card != $card) {
                // 删除卡号
                $redis->hDel("smartCards", $old_card);
            }
            $redis->hSetNx("smartCards", $card, $staff->id);
            FaceDevice::editPerson($staff->id);// 更新人脸设备信息
            return $this->buildSuccess();
        }
        return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
    }

    public function del(): Response {
        $flag = $this->request->get('flag', '');
        $ids = input('get.id');
        $redis = PoolRedis::instance();
        // 批量删除,id为staff的id
        if ($flag == 'all') {
            $list = (new AdminStaffIcCard())->whereIn('staff_id', $ids)
                ->where('is_delete', 0)->select();
            foreach ($list as $card) {
                $staff_type = $card->staff->type;
                $card->activate_time = 0;
                $card->ic_card = '';
                $card->save();
                $redis->hDel("smartCards", $card->ic_card);
                if ($staff_type == 0) {
                    $card->staff->smart_card = '';
                    $card->staff->save();
                }
                FaceDevice::editPerson($card->staff->id);// 更新人脸设备信息
                // IC卡和SIM卡都为空，回收掉编号
                if (empty($card->ic_card) || $card->ic_card=='00000000'
                    && (empty($card->sim_uid) || $card->sim_uid=='00000000000000000000')) {
                    $distributionKey = AdminStudentDormitory::NO_KEY.$card->staff->school_id.":".$card->student_dormitory_id;
                    $noKey = $distributionKey.':no';
                    $no = $redis->hGet($noKey, $card->staff_id);
                    if ($no){
                        $redis->hDel($noKey, $card->staff_id);
                        $poolKey = $distributionKey.':pool';
                        $redis->lPush($poolKey, $no);
                        Log::error("删除IC卡撤回编号 ".$card->student_dormitory_name.' 学生ID '.$card->staff_id.' 编号 '.$no);
                    }
                }
            }
            return $this->buildSuccess();
        }
        $model = (new AdminStaffIcCard())->where('id', input('get.id'))
            ->where('is_delete', 0)->find();
        if (!$model) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND);
        }
        $staff_type = $model->staff->type;
        $model->activate_time = 0;
        $model->ic_card = '';
        $model->save();
//        if ($staff_type > 0) {
//            $redis->hDel("smartCards", $model->ic_card);
//        } else {
        // 如果最后一条记录也被删除，则删除账号绑定的
        $exists = (new AdminStaffIcCard())->where('staff_id', $model->staff_id)
            ->whereNotNull('ic_card')
            ->where('ic_card', '<>', '')
            ->where('is_delete', 0)->findOrEmpty();
        if ($exists->isEmpty()) {
            $model->staff->smart_card = '';
            $model->staff->save();
            $redis->hDel("smartCards", $model->ic_card);
            FaceDevice::editPerson($model->staff->id);// 更新人脸设备信息
        }
//        }
        // IC卡和SIM卡都为空，回收掉编号
        if (empty($model->ic_card) || $model->ic_card=='00000000'
            && (empty($model->sim_uid) || $model->sim_uid=='00000000000000000000')) {
            $distributionKey = AdminStudentDormitory::NO_KEY.$model->staff->school_id.":".$model->student_dormitory_id;
            $noKey = $distributionKey.':no';
            $no = $redis->hGet($noKey, $model->staff_id);
            if ($no){
                $redis->hDel($noKey, $model->staff_id);
                $poolKey = $distributionKey.':pool';
                $redis->lPush($poolKey, $no);
                Log::error("删除IC卡撤回编号 ".$model->student_dormitory_name.' 学生ID '.$model->staff_id.' 编号 '.$no);
            }
        }
        return $this->buildSuccess();
    }

    public function upload(): Response {
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('excel_file');
        $school_id = request()->post('school_id');
        // 上传到本地服务器
        try {
            validate(['image'=>'fileSize:20480|fileExt:xls,xlsx'])
                ->check([$file]);
            $fileExtendName = substr(strrchr($file->getOriginalName(), '.'), 1);
            $filePath = $file->getPathname();
            if (is_file($filePath)){
                $cols = [['1' => 'number'],['2' =>'type'],['3'=>'student_no'],['4'=>'name'],['5'=>'sex'],['6' => 'entrance_time'],['7'=>'graduate_time'],['8'=>'phone'],['9'=>'student_dormitory_id'],['10'=>'ic_card']];
                $data = ExcelHandle::importExcel($filePath,$cols,$fileExtendName);

                $redis = PoolRedis::instance();
                $redis->multi(\Redis::PIPELINE);
                foreach ($data as $datum) {
                    $datum['school_id'] = $school_id;
                    $redis->lPush("upload_ic_card", serialize($datum));
                }
                $redis->exec();
                Queue::push('app\task\job\UploadSyncHandlerJob@fire', [
                    'model'=> AdminStaff::class,
                    'action' => 'upload_ic_card'
                ]);
            }
            return $this->buildSuccess();
        } catch (\think\exception\ValidateException $e) {
            return $this->buildFailed(ReturnCode::FILE_SAVE_ERROR, $e->getMessage());
        }
    }
}